from __future__ import annotations

import threading
import time
from abc import ABC, abstractmethod
from typing import Optional, Callable


class BaseWorker(ABC):
    """工作线程基类"""

    def __init__(self, name: str, condition: threading.Condition,
                 running_checker: Callable[[], bool], daemon: bool = True) -> None:
        self.name = name
        self.condition = condition
        self.running_checker = running_checker
        self.daemon = daemon

        # 线程状态
        self._thread: Optional[threading.Thread] = None
        self._is_running = False

    def start(self) -> None:
        """启动工作线程"""
        if self._thread is not None and self._thread.is_alive():
            return

        self._is_running = True
        self._thread = threading.Thread(
            target=self._worker_loop,
            name=self.name,
            daemon=self.daemon
        )
        self._thread.start()

    def stop(self) -> None:
        """停止工作线程"""
        self._is_running = False
        with self.condition:
            self.condition.notify_all()

        if self._thread is not None and self._thread.is_alive():
            self._thread.join(timeout=1.0)
            self._thread = None

    def is_alive(self) -> bool:
        """检查线程是否存活"""
        return self._thread is not None and self._thread.is_alive()

    def notify(self) -> None:
        """通知线程开始工作"""
        with self.condition:
            self.condition.notify()

    def _worker_loop(self) -> None:
        """工作线程主循环"""
        while self._is_running:
            try:
                # 等待工作条件满足
                with self.condition:
                    while not self._should_work() and self._is_running:
                        self.condition.wait(timeout=0.001)

                    if not self._is_running:
                        break

                    if not self._should_work():
                        continue

                # 执行具体工作
                self._run_work_loop()

            except Exception as e:
                print(f"[{self.name}] 工作线程异常: {e}")
                time.sleep(0.01)

    def _should_work(self) -> bool:
        """检查是否应该工作"""
        return self.running_checker()

    @abstractmethod
    def _run_work_loop(self) -> None:
        """执行具体工作循环"""
        pass

    def cleanup(self) -> None:
        """清理资源"""
        pass
